<!doctype html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8" >
    <meta http-equiv="X-UA-Compatible" content="IE=11,IE=10,IE=9,IE=8" >
    <meta name="baidu-site-verification" content="dIcXMeY8Ya" />
    
    <title>魔鬼在细节中 | JOKING</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0" >
    <meta name="keywords" content="JokingLove, 前端, Web, java, 博客，" >
    <meta name="description" content="JOKING 个人前端小站" >

    
    <link rel="alternative" href="/atom.xml" title="JOKING" type="application/atom+xml" >
    
    
    <link rel="shortcut icon" href="/knowledge/img/my-icon.png" >
    
    <link rel="stylesheet" href="/knowledge/css/style.css">
    <!--[if lt IE 9]>
    <script src="/knowledge/js/html5.js"></script>
    <![endif]-->
    
<script>
	var _hmt = _hmt || [];
	(function() {
	  var hm = document.createElement("script");
	  hm.src = "https://hm.baidu.com/hm.js?1eb8a2c234ac5bf6db839a19e3fbb5ee";
	  var s = document.getElementsByTagName("script")[0]; 
	  s.parentNode.insertBefore(hm, s);
	})();
</script>


<link rel="stylesheet" href="/knowledge/css/prism.css" type="text/css"></head>

<body class="home">
    <!--[if lt IE 9]>
    <div class="browsehappy">
        当前网页 <strong>不支持</strong>
        你正在使用的浏览器. 为了正常的访问, 请 <a href="http://browsehappy.com/">升级你的浏览器</a>.
    </div>
    <![endif]-->

    <!-- 博客头部 -->
    <header class="header">
    <section class="container header-main">
        <div class="logo">
            <a href="/">
                <div class="cover">
                    <span class="name">JOKING</span>
                    <span class="description">我的博客</span>
                </div>
            </a>
        </div>
        <div class="dropnav icon-paragraph-justify" id="JELON__btnDropNav"></div>
        <ul class="menu hidden" id="JELON__menu">
            
            <li rel="/knowledge/2017/08/09/魔鬼在细节中/index.html" class="item ">
                <a href="/knowledge/" title="首页" class="icon-home">&nbsp;首页</a>
            </li>
            
            <li rel="/knowledge/2017/08/09/魔鬼在细节中/index.html" class="item ">
                <a href="/knowledge/lab/" title="实验室" class="icon-lab">&nbsp;实验室</a>
            </li>
            
            <li rel="/knowledge/2017/08/09/魔鬼在细节中/index.html" class="item ">
                <a href="/knowledge/about/" title="关于" class="icon-about">&nbsp;关于</a>
            </li>
            
            <li rel="/knowledge/2017/08/09/魔鬼在细节中/index.html" class="item ">
                <a href="/knowledge/comment/" title="留言" class="icon-comment">&nbsp;留言</a>
            </li>
            
        </ul>
        <div class="profile clearfix">
            <div class="feeds fl">
                
                
                <p class="links">
                    
                        <a href="https://github.com/JokingLove" target="_blank">Github</a>
                        |
                    
                        <a href="https://gitee.com/jokinglove/" target="_blank">Gitee</a>
                        |
                    
                        <a href="https://coding.net/u/JokingLove" target="_blank">Coding</a>
                        |
                    
                        <a href="http://tongji.baidu.com" target="_blank">百度统计</a>
                        
                    
                </p>
                <p class="sns">
                    
                        <a href="http://weibo.com/JokingLove" class="sinaweibo" target="_blank"><b>■</b> 新浪微博</a>
                    
                        <a href="https://www.facebook.com/" class="qqweibo" target="_blank"><b>■</b> Facebook</a>
                    
                    <a href="javascript: void(0);" class="wechat">
                        <b>■</b>
                        公众号
                        <span class="popover">
                            <img src="/knowledge/img/wechat_mp.jpg" width="120" height="120" alt="我的微信订阅号">
                            <i class="arrow"></i>
                        </span>
                    </a>
                </p>
                
            </div>
            <div class="avatar fr">
                <img src="/images/user-3.jpg" alt="avatar" title="JOKING" >
            </div>
        </div>
    </section>
</header>


    <!-- 博客正文 -->
    <div class="container body clearfix">
        <section class="content">
            <div class="content-main widget">
                <!-- 文章页 -->
<!-- 文章 -->
<article class="post article">
    <header class="text-center">
        <h3 class="post-title"><span>魔鬼在细节中</span></h3>
    </header>
    <p class="post-meta text-center">
        JOKING 发表于
        <time datetime="2017-08-08T16:00:00.000Z">2017-08-09</time>
    </p>
    <div class="post-content">
        <p>作为一个it小司机，每次在写完代码，自己测了一遍都没发现什么问题，提交给测试的时候反馈回来一大堆的bug，检查发现很多其实都是一些很小的需要注意的细节，但却足以让你的程序瘫痪，平时注意这些小细节，可能会省去好多事。那么在编码中我们应该时候需要注意的规范有哪些呢，这也是在成为一个it老司机的路上必须要经过的一道坎，在这借鉴一下阿里大牛写的一遍魔鬼在细节中。<a id="more"></a></p>
<ol>
<li><p>防止空指针和下标越界<br>这是我最不喜欢看到的异常，尤其在核心框架中，我更愿看到信息详细的参数不合法异常，<br>这也是一个健状的程序开发人员，在写每一行代码都应在潜意识中防止的异常，<br>基本上要能确保一次写完的代码，在不测试的情况，都不会出现这两个异常才算合格。 </p>
</li>
<li><p>保证线程安全性和可见性<br>对于框架的开发人员，对线程安全性和可见性的深入理解是最基本的要求，<br>需要开发人员，在写每一行代码时都应在潜意识中确保其正确性，<br>因为这种代码，在小并发下做功能测试时，会显得很正常，<br>但在高并发下就会出现莫明其妙的问题，而且场景很难重现，极难排查。</p>
</li>
<li><p>尽早失败和前置断言<br>尽早失败也应该成为潜意识，在有传入参数和状态变化时，均在入口处全部断言，<br>一个不合法的值和状态，在第一时间就应报错，而不是等到要用时才报错，<br>因为等到要用时，可能前面已经修改其它相关状态，而在程序中很少有人去处理回滚逻辑，<br>这样报错后，其实内部状态可能已经混乱，极易在一个隐蔽分支上引发程序不可恢复。</p>
</li>
<li><p>分离可靠操作和不可靠操作<br>这里的可靠是狭义的指是否会抛出异常或引起状态不一致，<br>比如，写入一个线程安全的Map，可以认为是可靠的，<br>而写入数据库等，可以认为是不可靠的，<br>开发人员必须在写每一行代码时，都注意它的可靠性与否，<br>在代码中尽量划分开，并对失败做异常处理，<br>并为容错，自我保护，自动恢复或切换等补偿逻辑提供清晰的切入点，<br>保证后续增加的代码不至于放错位置，而导致原先的容错处理陷入混乱。</p>
</li>
<li><p>异常防御，但不忽略异常<br>这里讲的异常防御，指的是对非必须途径上的代码进行最大限度的容忍，<br>包括程序上的BUG，比如：获取程序的版本号，会通过扫描Manifest和jar包名称抓取版本号，<br>这个逻辑是辅助性的，但代码却不少，初步测试也没啥问题，<br>但应该在整个getVersion()中加上一个全函数的try-catch打印错误日志，并返回基本版本，<br>因为getVersion()可能存在未知特定场景异常，或被其他的开发人员误修改逻辑(但一般人员不会去掉try-catch)，<br>而如果它抛出异常会导致主流程异常，这是我们不希望看到的，<br>但这里要控制个度，不要随意try-catch，更不要无声无息的吃掉异常。 </p>
</li>
<li><p>缩小可变域和尽量final<br>如果一个类可以成为不变类(Immutable Class)，就优先将它设计成不变类，<br>不变类有天然的并发共享优势，减少同步或复制，而且可以有效帮忙分析线程安全的范围，<br>就算是可变类，对于从构造函数传入的引用，在类中持有时，最好将字段final，以免被中途误修改引用，<br>不要以为这个字段是私有的，这个类的代码都是我自己写的，不会出现对这个字段的重新赋值，<br>要考虑的一个因素是，这个代码可能被其他人修改，他不知道你的这个弱约定，final就是一个不变契约。 </p>
</li>
<li><p>降低修改时的误解性，不埋雷<br>前面不停的提到代码被其他人修改，这也开发人员要随时紧记的，<br>这个其他人包括未来的自己，你要总想着这个代码可能会有人去改它，<br>我应该给修改的人一点什么提示，让他知道我现在的设计意图，<br>而不要在程序里面加潜规则，或埋一些容易忽视的雷，<br>比如：你用null表示不可用，size等于0表示黑名单，<br>这就是一个雷，下一个修改者，包括你自己，都不会记得有这样的约定，<br>可能后面为了改某个其它BUG，不小心改到了这里，直接引爆故障。<br>对于这个例子，一个原则就是永远不要区分null引用和empty值。 </p>
</li>
<li><p>提高代码的可测性<br>这里的可测性主要指Mock的容易程度，和测试的隔离性，<br>至于测试的自动性，可重复性，非偶然性，无序性，完备性(全覆盖)，轻量性(可快速执行)，<br>一般开发人员，加上JUnit等工具的辅助基本都能做到，也能理解它的好处，只是工作量问题，<br>这里要特别强调的是测试用例的单一性(只测目标类本身)和隔离性(不传染失败)，<br>现在的测试代码，过于强调完备性，大量重复交叉测试，<br>看起来没啥坏处，但测试代码越多，维护代价越高，<br>经常出现的问题是，修改一行代码或加一个判断条件，引起100多个测试用例不通过，<br>时间一紧，谁有这个闲功夫去改这么多形态各异的测试用例？<br>久而久之，这个测试代码就已经不能真实反应代码现在的状况，很多时候会被迫绕过，<br>最好的情况是，修改一行代码，有且只有一行测试代码不通过，<br>如果修改了代码而测试用例还能通过，那也不行，表示测试没有覆盖到，<br>另外，可Mock性是隔离的基础，把间接依赖的逻辑屏蔽掉，<br>可Mock性的一个最大的杀手就是静态方法，尽量少用。</p>
</li>
</ol>
<p><a href="http://javatar.iteye.com/blog/1056664" target="_blank" rel="external">原文地址…</a></p>

    </div>
    <p class="post-meta">
        <span class="post-cat">分类：
            <a class="cat-link" href="/knowledge/categories/IT/">IT</a>
        </span>
        <span class="post-tags">
            标签：
            
    
        <a href="/knowledge/tags/编码规范/" title="编码规范">编码规范</a>
    

        </span>
    </p>
</article>
<!-- 分享按钮 -->

  <div class="article-share clearfix text-center">
    <div class="share-area">
      <span class="share-txt">分享到：</span>
      <a href="javascript: window.open('http://service.weibo.com/share/share.php?url=' + encodeURIComponent(location.href) + '&title=' + document.title + '&language=zh_cn');" class="share-icon weibo"></a>
      <a href="javascript: alert('请复制链接到微信并发送');" class="share-icon wechat"></a>
      <a href="javascript: window.open('http://sns.qzone.qq.com/cgi-bin/qzshare/cgi_qzshare_onekey?url=' + encodeURIComponent(location.href) + '&title=' + document.title);" class="share-icon qqzone"></a>
      <a href="javascript: window.open('http://connect.qq.com/widget/shareqq/index.html?url=' + encodeURIComponent(location.href) + '&desc=JOKING的个人博客&title=' + document.title + '&callback=' + encodeURIComponent(location.href));" class="share-icon qq"></a>
      <a href="javascript: window.open('http://shuo.douban.com/!service/share?href=' + encodeURIComponent(location.href) + '&name=' + document.title + '&text=' + document.title);" class="share-icon douban"></a>
    </div>
  </div>


<!-- 上一篇/下一篇 -->

<div class="article-nav clearfix">
    
    <span class="prev fl">
        上一篇<br >
        <a href="/knowledge/2017/08/13/spring-容器初始化的几种方式/">
            
                spring容器初始化的几种方式
            
        </a>
    </span>
    

    
    <span class="next fr">
        下一篇<br >
        <a href="/knowledge/2017/08/01/class-relationship/">
            
                类与类之间的关系
            
        </a>
    </span>
    
</div>

<!-- 文章评论 -->




<!--  网易云更贴已经暂停服务  -->


<!--  github issue 托管的评论  -->

  <script src="/knowledge/js/comment.js"></script>
  <div id="comments" class="comment">
    <!--
    <div class="sign-bar">
      GitHub 已登录!
      <span class="sign-link">登出</span>
    </div>
    <section class="box">
      <div class="com-avatar"><img src="/img/jelon.jpg" alt="avatar"></div>
      <div class="com-text">
        <div class="main">
          <textarea class="text-area-edited show" placeholder="欢迎评论！"></textarea>
          <div class="text-area-preview"></div>
        </div>
        <div class="switch">
          <div class="switch-item on">编辑</div>
          <div class="switch-item">预览</div>
        </div>
        <div class="button">提交</div>
      </div>
    </section>
    <section class="tips">注：评论支持 markdown 语法！</section>
    <section class="list-wrap">
      <ul class="list">
        <li>
          <div class="user-avatar">
            <a href="/">
              <img src="/img/jelon.jpg" alt="user-avatar">
            </a>
          </div>
          <div class="user-comment">
            <div class="user-comment-header">
              <span class="post-name">张德龙</span>
              <span class="post-time">2017年12月12日</span>
              <span class="like liked">已赞</span>
              <span class="like-num">2</span>
            </div>
            <div class="user-comment-body">333333</div>
          </div>
        </li>
        <li>
          <div class="user-avatar">
            <a href="/">
              <img src="/img/jelon.jpg" alt="user-avatar">
            </a>
          </div>
          <div class="user-comment">
            <div class="user-comment-header">
              <span class="post-name">刘德华</span>
              <span class="post-time">2017年12月12日</span>
              <span class="like">点赞</span>
              <span class="like-num">2</span>
            </div>
            <div class="user-comment-body">vvvvv</div>
          </div>
        </li>
      </ul>
      <div class="page-nav">
        <a href="javascript: void(0);" class="item">1</a>
        <a href="javascript: void(0);" class="item">2</a>
        <a href="javascript: void(0);" class="item current">3</a>
      </div>
    </section>
    -->
  </div>
  <script>
  JELON.Comment({
    container: 'comments',
    label: '魔鬼在细节中' || '2017/08/09/魔鬼在细节中/',
    owner: 'JokingLove',
    repo: 'site_comments',
    clientId: 'f4feedd2e2a90cdd85e0',
    clientSecret: '3745227591f3d83f1797b1a70ce2175352da026f'
  });
  </script>



            </div>

        </section>
        <!-- 侧栏部分 -->
<aside class="sidebar">
    <section class="widget">
        <h3 class="widget-hd"><strong>文章分类</strong></h3>
        <!-- 文章分类 -->
<ul class="widget-bd">
    
    <li>
        <a href="/knowledge/categories/瞎写/">瞎写</a>
        <span class="badge">(3)</span>
    </li>
    
    <li>
        <a href="/knowledge/categories/IT/">IT</a>
        <span class="badge">(6)</span>
    </li>
    
    <li>
        <a href="/knowledge/categories/上古神器/">上古神器</a>
        <span class="badge">(3)</span>
    </li>
    
    <li>
        <a href="/knowledge/categories/其他/">其他</a>
        <span class="badge">(1)</span>
    </li>
    
</ul>
    </section>

    
    <section class="widget">
        <h3 class="widget-hd"><strong>热门标签</strong></h3>
        <!-- 文章标签 -->
<div class="widget-bd tag-wrap">
  
    	<a class="tag-item" href="/knowledge/tags/随记/" title="(2)">随记</a>
	  
    	<a class="tag-item" href="/knowledge/tags/1024/" title="(1)">1024</a>
	  
    	<a class="tag-item" href="/knowledge/tags/面向对象/" title="(1)">面向对象</a>
	  
    	<a class="tag-item" href="/knowledge/tags/git/" title="(2)">git</a>
	  
    	<a class="tag-item" href="/knowledge/tags/hexo/" title="(1)">hexo</a>
	  
    	<a class="tag-item" href="/knowledge/tags/设计模式/" title="(1)">设计模式</a>
	  
    	<a class="tag-item" href="/knowledge/tags/maven/" title="(1)">maven</a>
	  
    	<a class="tag-item" href="/knowledge/tags/python/" title="(1)">python</a>
	  
    	<a class="tag-item" href="/knowledge/tags/spring-boot/" title="(1)">spring-boot</a>
	  
    	<a class="tag-item" href="/knowledge/tags/spring/" title="(1)">spring</a>
	  
    	<a class="tag-item" href="/knowledge/tags/编码规范/" title="(1)">编码规范</a>
	  
</div>
    </section>
    

    

    
</aside>
<!-- / 侧栏部分 -->
    </div>

    <!-- 博客底部 -->
    <footer class="footer">
    &copy;
    
        2016-2017
    

    <a href="/knowledge/">JOKING Loves You</a>
</footer>
<div class="back-to-top" id="JELON__backToTop" title="返回顶部">返回顶部</div>
<!-- 添加百度自动推送 -->
<!-- <script>
(function(){
    var bp = document.createElement('script');
    var curProtocol = window.location.protocol.split(':')[0];
    if (curProtocol === 'https') {
        bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';        
    }
    else {
        bp.src = 'http://push.zhanzhang.baidu.com/push.js';
    }
    var s = document.getElementsByTagName("script")[0];
    s.parentNode.insertBefore(bp, s);
})();
</script> -->


    <!--博客js脚本 -->
    <!-- 这里放网站js脚本 -->
<script src="/knowledge/js/main.js"></script>

<!-- disqus 评论相关js -->

    <!-- 百度统计 -->
    
<script>
	var _hmt = _hmt || [];
	(function() {
	  var hm = document.createElement("script");
	  hm.src = "https://hm.baidu.com/hm.js?1eb8a2c234ac5bf6db839a19e3fbb5ee";
	  var s = document.getElementsByTagName("script")[0]; 
	  s.parentNode.insertBefore(hm, s);
	})();
</script>


</body>
</html>